import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.ArrayList;
import java.util.Collections;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * 牌桌类，提供游戏的运行场景
 */
public class Table extends World {
    ArrayList<Card> cards = new ArrayList<Card>();  //声明一个保存扑克牌对象的集合cards 
    // 常量定义
    public static final int EASY = 5;
    public static final int MEDIUM = 8; // 修改为8对
    public static final int HARD = 13; // 修改为13对
    
    private int currentScore; // 当前分数
    private int bestScore; // 最佳成绩
    private GreenfootImage scoreBoard; // 记分板图像
    
    private int difficulty;
    //存储路径
    private static final String SCORE_DIR = "D:/Card_Score/";
    //Table类的构造方法
    public Table(int _difficulty,int height,int width) {   
        super(height, width, 1);
        
        currentScore = 0; // 初始分数
        bestScore=0;
        bestScore = loadBestScore(difficulty); // 加载最佳成绩
        scoreBoard = new GreenfootImage(getWidth(), getHeight());//初始化scoreBoard图像
        difficulty = _difficulty;
        int totalPairs = _difficulty; // 计算对数
        for (int i = 1; i <= totalPairs; i++) { // 添加对数的牌
            cards.add(new Card(i));
            cards.add(new Card(i));
        }
        Collections.shuffle(cards); // 打乱牌的顺序
        
        int x = 100, y = 100;   // 牌桌上摆放牌的起点坐标
        int rows = (totalPairs * 2+4) / 5; // 计算需要的行数（每行5张）

        for (int i = 0; i < rows; i++) { // 根据行数进行循环
            for (int j = 0; j < 5; j++) { // 每行5张牌
                int index = i * 5 + j; // 计算当前牌的索引
                if (index < cards.size()) { // 确保索引在范围内
                    addObject(cards.get(index), x, y);
                    x += cards.get(index).getImage().getWidth() + 20; // 更新x坐标
                }
            }
            x = 100; // 重置x坐标
            y += cards.get(0).getImage().getHeight() + 20; // 更新y坐标
        }
        
        // 在构造方法末尾
        Info info = new Info("游玩须知", "游戏说明：本游戏为记忆翻牌游戏。\n游戏玩法：玩家通过点击盖住的牌使其翻面，\n如果为两张相同的牌，则消去，\n若为两张不同的牌，则盖住，玩家重新翻牌\n\n需知：本游戏在做持久化得分系统中处理的不好，\n由于技术原因未能完成，\n但是会在D盘留下一个Card_Score文件夹，\n用来记录玩家最好得分，\n如果看到这样的文件夹请不要意外。\n\n点击关闭弹窗即代表你已知晓");
        addObject(info, getWidth() / 2, getHeight() / 2); // 中间显示弹窗

    }
    
    //act()方法是游戏单步执行的动作
    public void act() {     
        // 处理牌翻转逻辑
        HandleCards();
        
        // 更新记分板
        ShowScore();
        
        // 让每张牌随机移动
        for (Card card : cards) {
            card.moveRandom();
        }
    }
    private void ShowScore()
    {
        // 更新显示分数
        if (scoreBoard != null) {
            scoreBoard.clear();
            scoreBoard.drawString("当前分数: " + currentScore, 500, 50);
            scoreBoard.drawString("最佳成绩: " + bestScore, 500, 80);
        }

        // 只在右上角绘制分数
        getBackground().drawImage(scoreBoard, 0, 0);
    }
    
    private void HandleCards()
    {
        int count = 0, card1Value = 0, card2Value = 0; // count表示牌桌上被翻开的第几张牌
        Card card1 = null, card2 = null;
        for (int i = 0; i < cards.size(); i++) { // 遍历所有牌
            if (cards.get(i).getFaceup() == true) { // 如果这张牌是翻开的
                count++; // 计数
                if (count == 1) { // 第一张
                    card1 = cards.get(i);
                    card1Value = card1.getValue();                   
                }
                if (count == 2) { // 第二张
                    card2 = cards.get(i);
                    card2Value = card2.getValue();
                    if (card1Value == card2Value) {
                        Greenfoot.playSound("WaterDrop.wav");
                        Greenfoot.delay(15);
                        removeObject(card1);
                        removeObject(card2);
                        cards.remove(card1);
                        cards.remove(card2);
                        if (cards.size() == 0) {
                            EndGame();
                        }
                    } else {
                        Greenfoot.delay(15);
                        card1.turnFaceDown();
                        card2.turnFaceDown();
                    }
                }
            }
        }
    }
    private void EndGame()
    {
        if (cards.size() == 0) {
            if (currentScore < bestScore) {
                bestScore = currentScore; // 更新最佳成绩
                saveBestScore(difficulty); // 保存最佳分数
            }
            RestartButton restartButton = new RestartButton();
            addObject(restartButton,getWidth() / 2, getHeight() / 2 + 50);
            showText("游戏结束", 300, 200);

        }

    }
    public void incrementScore() {
        currentScore++; // 每次点击牌时增加分数
    }
    private int loadBestScore(int difficulty) {
        // 从文件中加载最佳分数，示例：
        // 创建文件夹（如果不存在）
        File directory = new File(SCORE_DIR);
        if (!directory.exists()) {
            directory.mkdirs(); // 创建文件夹
        }

        File file = new File(SCORE_DIR + "best_score_" + difficulty + ".txt");
        if (file.exists()) {
            try (Scanner scanner = new Scanner(file)) {
                return scanner.nextInt(); // 读取分数
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        return Integer.MAX_VALUE; // 如果文件不存在，则返回最大值
    }

    private void saveBestScore(int difficulty) {
        // 创建文件夹（如果不存在）
        File directory = new File(SCORE_DIR);
        if (!directory.exists()) {
            directory.mkdirs(); // 创建文件夹
        }   

        File file = new File(SCORE_DIR + "best_score_" + difficulty + ".txt");
        try (PrintWriter writer = new PrintWriter(file)) {
            writer.println(bestScore);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

}
